package domain

import (
	"encoding/xml"
	"fmt"

	log "github.com/sirupsen/logrus"
	"libvirt.org/go/libvirt"
	"libvirt.org/go/libvirtxml"

	"github.com/yourusername/lvm-manager/internal/events"
	"github.com/yourusername/lvm-manager/internal/libvirtconn"
)

// Service 虚拟机领域服务
type Service struct {
	connManager    *libvirtconn.ConnManager
	eventManager   *events.Manager
	consoleService *ConsoleService // 新增控制台服务
	logger         *log.Logger
}

// NewService 创建领域服务
func NewService(connManager *libvirtconn.ConnManager, eventManager *events.Manager, logger *log.Logger) *Service {
	return &Service{
		connManager:    connManager,
		eventManager:   eventManager,
		consoleService: NewConsoleService(connManager, logger),
		logger:         logger,
	}
}

// DomainInfo Domain 信息结构
type DomainInfo struct {
	UUID       string   `json:"uuid"`
	Name       string   `json:"name"`
	State      string   `json:"state"`
	MaxMemory  uint64   `json:"max_memory"`
	Memory     uint64   `json:"memory"`
	CPUs       uint     `json:"cpus"`
	CPUTime    uint64   `json:"cpu_time"`
	Autostart  bool     `json:"autostart"`
	Persistent bool     `json:"persistent"`
	XMLConfig  string   `json:"xml_config,omitempty"`
	Ipv4Addrs  []string `json:"ipv4_addrs,omitempty"`
}

// CreateSpec 创建 Domain 的高层规格
type CreateSpec struct {
	Name        string `json:"name" binding:"required"`
	Memory      uint   `json:"memory" binding:"required"` // MiB
	VCPUs       uint   `json:"vcpus" binding:"required"`
	DiskPath    string `json:"disk_path" binding:"required"`
	DiskSize    uint   `json:"disk_size"`    // GiB, 如果需要创建新盘
	NetworkType string `json:"network_type"` // "bridge", "network", "user"
	NetworkName string `json:"network_name"` // bridge 名或 network 名
	OSType      string `json:"os_type"`      // "linux", "windows"
	BootDevice  string `json:"boot_device"`  // "hd", "cdrom"
}

// UpdateSpec 更新 Domain 的高层规格
type UpdateSpec struct {
	Name      string `json:"name"`
	Memory    uint   `json:"memory"` // MiB
	VCPUs     uint   `json:"vcpus"`
	Autostart *bool  `json:"autostart"`
	// 注意：某些配置（如磁盘路径）在虚拟机创建后不能修改
}

// CreateMethod 虚拟机创建方式枚举
type CreateMethod string

const (
	CreateMethodLocalISO   CreateMethod = "local_iso"   // 从本地ISO创建
	CreateMethodNetwork    CreateMethod = "network"     // 从网络安装创建
	CreateMethodImportDisk CreateMethod = "import_disk" // 从磁盘映像导入
	CreateMethodManual     CreateMethod = "manual"      // 手动创建
)

// VMCreateWizardSpec 虚拟机创建向导规格
type VMCreateWizardSpec struct {
	Method CreateMethod `json:"method" binding:"required"`

	// 基本信息
	Name        string `json:"name" binding:"required"`
	Description string `json:"description,omitempty"`
	OSType      string `json:"os_type"`
	OSVersion   string `json:"os_version"`

	// 资源配置
	VCPUs      uint   `json:"vcpus" binding:"required"`
	Memory     uint   `json:"memory" binding:"required"` // MiB
	MemoryUnit string `json:"memory_unit"`               // "MB" 或 "GB"
	CPUModel   string `json:"cpu_model"`

	// 存储配置
	StoragePool string `json:"storage_pool"`
	DiskSize    uint   `json:"disk_size"`   // GB
	DiskFormat  string `json:"disk_format"` // "qcow2", "raw"
	DiskBus     string `json:"disk_bus"`    // "virtio", "ide", "scsi"
	CacheMode   string `json:"cache_mode"`  // "writeback", "writethrough"

	// 网络配置
	NetworkType  string `json:"network_type"`
	NetworkName  string `json:"network_name"`
	NetworkModel string `json:"network_model"`
	MACAddress   string `json:"mac_address"`

	// 启动选项
	BootOrder       []string `json:"boot_order"` // ["cdrom", "hd", "network"]
	Autostart       bool     `json:"autostart"`
	BootDelay       uint     `json:"boot_delay"` // 秒
	Loader          string   `json:"loader"`     // "bios", "uefi"
	Graphics        string   `json:"graphics"`   // "vnc", "spice"
	DisplayProtocol string   `json:"display_protocol"`

	// 本地ISO配置
	LocalISOPath  string `json:"local_iso_path,omitempty"`
	LocalISOCDROM bool   `json:"local_iso_cdrom"` // 是否使用CD-ROM设备

	// 网络安装配置
	NetworkSource string `json:"network_source,omitempty"` // HTTP/FTP URL
	NetworkKernel string `json:"network_kernel,omitempty"` // 内核路径
	NetworkInitrd string `json:"network_initrd,omitempty"` // initrd路径
	NetworkExtra  string `json:"network_extra,omitempty"`  // 额外内核参数

	// 磁盘导入配置
	ImportDiskPath string `json:"import_disk_path,omitempty"` // 导入的磁盘路径
	ImportCopy     bool   `json:"import_copy"`                // 是否复制磁盘

	// 磁盘路径（用于所有方法）
	DiskPath string `json:"disk_path,omitempty"`

	// 手动创建配置
	CustomXML string `json:"custom_xml,omitempty"` // 自定义XML配置
}

// List 列出所有 domains
func (s *Service) List(includeInactive bool) ([]DomainInfo, error) {
	var domains []DomainInfo

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		flags := libvirt.CONNECT_LIST_DOMAINS_ACTIVE
		if includeInactive {
			flags |= libvirt.CONNECT_LIST_DOMAINS_INACTIVE
		}

		doms, err := conn.ListAllDomains(flags)
		if err != nil {
			return fmt.Errorf("failed to list domains: %w", err)
		}

		for _, dom := range doms {
			info, err := s.getDomainInfo(&dom, false)
			if err != nil {
				log.Warnf("Failed to get info for domain: %v", err)
				continue
			}
			domains = append(domains, *info)
			dom.Free()
		}
		return nil
	})

	return domains, err
}

// Get 获取单个 domain 详细信息（通过名称）
func (s *Service) Get(name string, includeXML bool) (*DomainInfo, error) {
	var info *DomainInfo

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		info, err = s.getDomainInfo(dom, includeXML)
		return err
	})

	return info, err
}

// GetByUUID 通过UUID获取单个 domain 详细信息
func (s *Service) GetByUUID(uuid string, includeXML bool) (*DomainInfo, error) {
	var info *DomainInfo

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		info, err = s.getDomainInfo(dom, includeXML)
		return err
	})

	return info, err
}

// Exists 检查指定名称的 domain 是否存在
func (s *Service) Exists(name string) (bool, error) {
	var exists bool

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		_, err := conn.LookupDomainByName(name)
		if err != nil {
			// 检查错误类型，如果是因为domain不存在则返回false，否则返回错误
			if libvirtError, ok := err.(libvirt.Error); ok {
				if libvirtError.Code == libvirt.ERR_NO_DOMAIN {
					exists = false
					return nil
				}
			}
			// 其他错误返回
			return err
		}

		// 没有错误说明domain存在
		exists = true
		return nil
	})

	return exists, err
}

// ExistsByUUID 检查指定UUID的 domain 是否存在
func (s *Service) ExistsByUUID(uuid string) (bool, error) {
	var exists bool

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		_, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			// 检查错误类型，如果是因为domain不存在则返回false，否则返回错误
			if libvirtError, ok := err.(libvirt.Error); ok {
				if libvirtError.Code == libvirt.ERR_NO_DOMAIN {
					exists = false
					return nil
				}
			}
			// 其他错误返回
			return err
		}

		// 没有错误说明domain存在
		exists = true
		return nil
	})

	return exists, err
}

// getDomainInfo 从 libvirt.Domain 提取信息
func (s *Service) getDomainInfo(dom *libvirt.Domain, includeXML bool) (*DomainInfo, error) {
	name, err := dom.GetName()
	if err != nil {
		return nil, err
	}

	uuid, err := dom.GetUUIDString()
	if err != nil {
		return nil, err
	}

	state, _, err := dom.GetState()
	if err != nil {
		return nil, err
	}

	info, err := dom.GetInfo()
	if err != nil {
		return nil, err
	}

	autostart, err := dom.GetAutostart()
	if err != nil {
		autostart = false
	}

	persistent, err := dom.IsPersistent()
	if err != nil {
		persistent = false
	}

	// 获取 IPv4 地址信息
	var ipv4Addrs []string
	if state == libvirt.DOMAIN_RUNNING {
		// 只有在虚拟机运行时才能获取IP地址
		ifaces, err := dom.ListAllInterfaceAddresses(libvirt.DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE)
		if err == nil {
			for _, iface := range ifaces {
				for _, addr := range iface.Addrs {
					if addr.Type == libvirt.IP_ADDR_TYPE_IPV4 {
						ipv4Addrs = append(ipv4Addrs, addr.Addr)
					}
				}
			}
		}
	}

	domInfo := &DomainInfo{
		UUID:       uuid,
		Name:       name,
		State:      domainStateToString(state),
		MaxMemory:  info.MaxMem,
		Memory:     info.Memory,
		CPUs:       info.NrVirtCpu,
		CPUTime:    info.CpuTime,
		Autostart:  autostart,
		Persistent: persistent,
		Ipv4Addrs:  ipv4Addrs,
	}

	if includeXML {
		xmlDesc, err := dom.GetXMLDesc(0)
		if err != nil {
			log.Warnf("Failed to get XML for domain %s: %v", name, err)
		} else {
			domInfo.XMLConfig = xmlDesc
		}
	}

	return domInfo, nil
}

// Create 通过高层规格创建 domain
func (s *Service) Create(spec *CreateSpec) (*DomainInfo, error) {
	// 构建 domain XML
	domainXML := s.buildDomainXML(spec)

	xmlBytes, err := xml.MarshalIndent(domainXML, "", "  ")
	if err != nil {
		return nil, fmt.Errorf("failed to marshal domain XML: %w", err)
	}

	log.Debugf("Creating domain with XML:\n%s", string(xmlBytes))

	var info *DomainInfo
	err = s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.DomainDefineXML(string(xmlBytes))
		if err != nil {
			return fmt.Errorf("failed to define domain: %w", err)
		}
		defer dom.Free()

		info, err = s.getDomainInfo(dom, false)
		return err
	})

	return info, err
}

// CreateFromXML 直接从 XML 创建 domain
func (s *Service) CreateFromXML(xmlConfig string) (*DomainInfo, error) {
	var info *DomainInfo

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.DomainDefineXML(xmlConfig)
		if err != nil {
			return fmt.Errorf("failed to define domain: %w", err)
		}
		defer dom.Free()

		info, err = s.getDomainInfo(dom, false)
		return err
	})

	return info, err
}

// Start 启动 domain
func (s *Service) Start(name string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Create(); err != nil {
			return fmt.Errorf("failed to start domain: %w", err)
		}

		log.Infof("Domain %s started", name)
		return nil
	})
}

// StartByUUID 通过UUID启动 domain
func (s *Service) StartByUUID(uuid string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Create(); err != nil {
			return fmt.Errorf("failed to start domain: %w", err)
		}

		name, _ := dom.GetName()
		log.Infof("Domain %s (UUID: %s) started", name, uuid)
		return nil
	})
}

// Shutdown 关闭 domain (优雅)
func (s *Service) Shutdown(name string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Shutdown(); err != nil {
			return fmt.Errorf("failed to shutdown domain: %w", err)
		}

		log.Infof("Domain %s shutdown initiated", name)
		return nil
	})
}

// ShutdownByUUID 通过UUID关闭 domain (优雅)
func (s *Service) ShutdownByUUID(uuid string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Shutdown(); err != nil {
			return fmt.Errorf("failed to shutdown domain: %w", err)
		}

		name, _ := dom.GetName()
		log.Infof("Domain %s (UUID: %s) shutdown initiated", name, uuid)
		return nil
	})
}

// Destroy 强制关闭 domain
func (s *Service) Destroy(name string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Destroy(); err != nil {
			return fmt.Errorf("failed to destroy domain: %w", err)
		}

		log.Infof("Domain %s destroyed", name)
		return nil
	})
}

// DestroyByUUID 通过UUID强制关闭 domain
func (s *Service) DestroyByUUID(uuid string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Destroy(); err != nil {
			return fmt.Errorf("failed to destroy domain: %w", err)
		}

		name, _ := dom.GetName()
		log.Infof("Domain %s (UUID: %s) destroyed", name, uuid)
		return nil
	})
}

// Reboot 重启 domain
func (s *Service) Reboot(name string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Reboot(libvirt.DOMAIN_REBOOT_DEFAULT); err != nil {
			return fmt.Errorf("failed to reboot domain: %w", err)
		}

		log.Infof("Domain %s reboot initiated", name)
		return nil
	})
}

// RebootByUUID 通过UUID重启 domain
func (s *Service) RebootByUUID(uuid string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Reboot(libvirt.DOMAIN_REBOOT_DEFAULT); err != nil {
			return fmt.Errorf("failed to reboot domain: %w", err)
		}

		name, _ := dom.GetName()
		log.Infof("Domain %s (UUID: %s) reboot initiated", name, uuid)
		return nil
	})
}

// Suspend 暂停 domain
func (s *Service) Suspend(name string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Suspend(); err != nil {
			return fmt.Errorf("failed to suspend domain: %w", err)
		}

		log.Infof("Domain %s suspended", name)
		return nil
	})
}

// SuspendByUUID 通过UUID暂停 domain
func (s *Service) SuspendByUUID(uuid string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Suspend(); err != nil {
			return fmt.Errorf("failed to suspend domain: %w", err)
		}

		name, _ := dom.GetName()
		log.Infof("Domain %s (UUID: %s) suspended", name, uuid)
		return nil
	})
}

// Resume 恢复 domain
func (s *Service) Resume(name string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Resume(); err != nil {
			return fmt.Errorf("failed to resume domain: %w", err)
		}

		log.Infof("Domain %s resumed", name)
		return nil
	})
}

// ResumeByUUID 通过UUID恢复 domain
func (s *Service) ResumeByUUID(uuid string) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		if err := dom.Resume(); err != nil {
			return fmt.Errorf("failed to resume domain: %w", err)
		}

		name, _ := dom.GetName()
		log.Infof("Domain %s (UUID: %s) resumed", name, uuid)
		return nil
	})
}

// Undefine 删除 domain 定义
func (s *Service) Undefine(name string, force bool) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		// 如果是强制删除，先尝试销毁正在运行的 domain
		if force {
			state, _, err := dom.GetState()
			if err != nil {
				log.Warnf("Failed to get domain state: %v", err)
			} else if state == libvirt.DOMAIN_RUNNING {
				log.Infof("Force deleting running domain %s, attempting to destroy it first", name)
				if err := dom.Destroy(); err != nil {
					log.Warnf("Failed to destroy running domain %s: %v", name, err)
				}
			}
		}

		if err := dom.Undefine(); err != nil {
			return fmt.Errorf("failed to undefine domain: %w", err)
		}

		log.Infof("Domain %s undefined", name)
		return nil
	})
}

// UndefineByUUID 通过UUID删除 domain 定义
func (s *Service) UndefineByUUID(uuid string, force bool) error {
	return s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		// 获取域名用于日志
		name, _ := dom.GetName()

		// 如果是强制删除，先尝试销毁正在运行的 domain
		if force {
			state, _, err := dom.GetState()
			if err != nil {
				log.Warnf("Failed to get domain state: %v", err)
			} else if state == libvirt.DOMAIN_RUNNING {
				log.Infof("Force deleting running domain %s (UUID: %s), attempting to destroy it first", name, uuid)
				if err := dom.Destroy(); err != nil {
					log.Warnf("Failed to destroy running domain %s: %v", name, err)
				}
			}
		}

		if err := dom.Undefine(); err != nil {
			return fmt.Errorf("failed to undefine domain: %w", err)
		}

		log.Infof("Domain %s (UUID: %s) undefined", name, uuid)
		return nil
	})
}

// buildDomainXML 从 CreateSpec 构建 libvirtxml.Domain
func (s *Service) buildDomainXML(spec *CreateSpec) *libvirtxml.Domain {
	osType := "hvm"
	if spec.OSType == "linux" {
		osType = "linux"
	}

	bootDev := "hd"
	if spec.BootDevice != "" {
		bootDev = spec.BootDevice
	}

	domain := &libvirtxml.Domain{
		Type: "kvm",
		Name: spec.Name,
		Memory: &libvirtxml.DomainMemory{
			Value: uint(spec.Memory),
			Unit:  "MiB",
		},
		VCPU: &libvirtxml.DomainVCPU{
			Value: uint(spec.VCPUs),
		},
		OS: &libvirtxml.DomainOS{
			Type: &libvirtxml.DomainOSType{
				Type: osType,
			},
			BootDevices: []libvirtxml.DomainBootDevice{
				{Dev: bootDev},
			},
		},
		Devices: &libvirtxml.DomainDeviceList{
			Disks: []libvirtxml.DomainDisk{
				{
					Device: "disk",
					Driver: &libvirtxml.DomainDiskDriver{
						Name: "qemu",
						Type: "qcow2",
					},
					Source: &libvirtxml.DomainDiskSource{
						File: &libvirtxml.DomainDiskSourceFile{
							File: spec.DiskPath,
						},
					},
					Target: &libvirtxml.DomainDiskTarget{
						Dev: "vda",
						Bus: "virtio",
					},
				},
			},
			Graphics: []libvirtxml.DomainGraphic{
				{
					VNC: &libvirtxml.DomainGraphicVNC{
						Port:     -1, // 自动分配
						AutoPort: "yes",
						Listen:   "127.0.0.1",
					},
				},
			},
		},
	}

	// 添加网络接口
	if spec.NetworkType != "" {
		netInterface := libvirtxml.DomainInterface{
			Model: &libvirtxml.DomainInterfaceModel{
				Type: "virtio",
			},
		}

		switch spec.NetworkType {
		case "bridge":
			netInterface.Source = &libvirtxml.DomainInterfaceSource{
				Bridge: &libvirtxml.DomainInterfaceSourceBridge{
					Bridge: spec.NetworkName,
				},
			}
		case "network":
			netInterface.Source = &libvirtxml.DomainInterfaceSource{
				Network: &libvirtxml.DomainInterfaceSourceNetwork{
					Network: spec.NetworkName,
				},
			}
		case "user":
			netInterface.Source = &libvirtxml.DomainInterfaceSource{
				User: &libvirtxml.DomainInterfaceSourceUser{},
			}
		}

		domain.Devices.Interfaces = []libvirtxml.DomainInterface{netInterface}
	}

	return domain
}

// domainStateToString 将 domain 状态转为字符串
func domainStateToString(state libvirt.DomainState) string {
	switch state {
	case libvirt.DOMAIN_NOSTATE:
		return "nostate"
	case libvirt.DOMAIN_RUNNING:
		return "running"
	case libvirt.DOMAIN_BLOCKED:
		return "blocked"
	case libvirt.DOMAIN_PAUSED:
		return "paused"
	case libvirt.DOMAIN_SHUTDOWN:
		return "shutdown"
	case libvirt.DOMAIN_SHUTOFF:
		return "shutoff"
	case libvirt.DOMAIN_CRASHED:
		return "crashed"
	case libvirt.DOMAIN_PMSUSPENDED:
		return "pmsuspended"
	default:
		return "unknown"
	}
}

// VNCInfo VNC连接信息
type VNCInfo struct {
	Host                string `json:"host"`
	Port                int    `json:"port"`           // VNC 原生端口 (5900 + display)
	WebSocketPort       int    `json:"websocket_port"` // WebSocket 端口 (6900 + display)
	Password            string `json:"password,omitempty"`
	ConsoleWebSocketURL string `json:"console_websocket_url"` // 控制台WebSocket URL
}

// ConsoleStream 控制台流信息
// 用于表示虚拟机控制台的流连接
// 注意：这个结构体现在在console.go中定义，此处仅保留注释说明

// OpenConsole 打开域的控制台流
func (s *Service) OpenConsole(name string, consoleType string) (*ConsoleStream, error) {
	// 获取域的UUID
	uuid, err := s.getDomainUUIDByName(name)
	if err != nil {
		return nil, err
	}

	// 使用控制台服务打开控制台
	return s.consoleService.OpenConsoleByUUID(uuid, consoleType)
}

// OpenConsoleByUUID 通过UUID打开域的控制台流
func (s *Service) OpenConsoleByUUID(uuid string, consoleType string) (*ConsoleStream, error) {
	return s.consoleService.OpenConsoleByUUID(uuid, consoleType)
}

// findAvailableConsoleDevice 查找可用的控制台设备
func (s *Service) findAvailableConsoleDevice(dom *libvirt.Domain, preferredType string) string {
	// 获取域的XML描述
	xmlDesc, err := dom.GetXMLDesc(0)
	if err != nil {
		log.Debugf("Failed to get domain XML for console device detection: %v", err)
		return ""
	}

	// 解析XML
	var domainDef libvirtxml.Domain
	if err := xml.Unmarshal([]byte(xmlDesc), &domainDef); err != nil {
		log.Debugf("Failed to parse domain XML for console device detection: %v", err)
		return ""
	}

	// 根据首选类型查找设备
	switch preferredType {
	case "console":
		if domainDef.Devices != nil && len(domainDef.Devices.Consoles) > 0 {
			// 返回第一个控制台设备
			return fmt.Sprintf("console%d", 0)
		}
	case "serial":
		if domainDef.Devices != nil && len(domainDef.Devices.Serials) > 0 {
			// 返回第一个串行端口设备
			return fmt.Sprintf("serial%d", 0)
		}
	case "parallel":
		if domainDef.Devices != nil && len(domainDef.Devices.Parallels) > 0 {
			// 返回第一个并行端口设备
			return fmt.Sprintf("parallel%d", 0)
		}
	case "channel":
		if domainDef.Devices != nil && len(domainDef.Devices.Channels) > 0 {
			// 返回第一个通道设备
			return fmt.Sprintf("channel%d", 0)
		}
	}

	// 默认返回空字符串
	return ""
}

// getActualVNCDisplay 获取运行时实际分配的VNC显示编号
func (s *Service) getActualVNCDisplay(dom *libvirt.Domain) (int, error) {
	// 获取域的XML描述（运行时状态）
	xmlDesc, err := dom.GetXMLDesc(libvirt.DOMAIN_XML_SECURE)
	if err != nil {
		return 0, err
	}

	// 解析XML
	var domainDef libvirtxml.Domain
	if err := xml.Unmarshal([]byte(xmlDesc), &domainDef); err != nil {
		return 0, err
	}

	// 查找VNC图形设备
	if domainDef.Devices != nil && len(domainDef.Devices.Graphics) > 0 {
		for _, graphic := range domainDef.Devices.Graphics {
			if graphic.VNC != nil && graphic.VNC.Port > 0 {
				// 返回实际的显示编号
				return graphic.VNC.Port, nil
			}
		}
	}

	return 0, fmt.Errorf("no VNC display found in runtime XML")
}

// CreateWithWizard 使用向导规格创建虚拟机
func (s *Service) CreateWithWizard(spec *VMCreateWizardSpec) (*DomainInfo, error) {
	// 根据创建方法选择不同的创建逻辑
	switch spec.Method {
	case CreateMethodLocalISO:
		return s.createFromLocalISO(spec)
	case CreateMethodNetwork:
		return s.createFromNetwork(spec)
	case CreateMethodImportDisk:
		return s.createFromImportDisk(spec)
	case CreateMethodManual:
		return s.createManually(spec)
	default:
		return nil, fmt.Errorf("unsupported create method: %s", spec.Method)
	}
}

// createFromLocalISO 从本地ISO创建虚拟机
func (s *Service) createFromLocalISO(spec *VMCreateWizardSpec) (*DomainInfo, error) {
	// 验证必需参数
	if spec.LocalISOPath == "" {
		return nil, fmt.Errorf("local ISO path is required for local ISO creation")
	}

	// 构建XML配置
	domainXML := s.buildWizardDomainXML(spec)

	// 添加CD-ROM设备用于ISO引导
	if spec.LocalISOCDROM {
		cdromDisk := libvirtxml.DomainDisk{
			Device: "cdrom",
			Driver: &libvirtxml.DomainDiskDriver{
				Name: "qemu",
				Type: "raw",
			},
			Source: &libvirtxml.DomainDiskSource{
				File: &libvirtxml.DomainDiskSourceFile{
					File: spec.LocalISOPath,
				},
			},
			Target: &libvirtxml.DomainDiskTarget{
				Dev: "hda",
				Bus: "ide",
			},
			ReadOnly: &libvirtxml.DomainDiskReadOnly{},
		}
		domainXML.Devices.Disks = append(domainXML.Devices.Disks, cdromDisk)

		// 设置启动顺序为CD-ROM优先
		if len(spec.BootOrder) == 0 {
			spec.BootOrder = []string{"cdrom", "hd"}
		}
	}

	return s.createDomainFromXML(spec.Name, domainXML)
}

// createFromNetwork 从网络安装创建虚拟机
func (s *Service) createFromNetwork(spec *VMCreateWizardSpec) (*DomainInfo, error) {
	// 验证必需参数
	if spec.NetworkSource == "" {
		return nil, fmt.Errorf("network source URL is required for network installation")
	}

	// 构建XML配置
	domainXML := s.buildWizardDomainXML(spec)

	// 配置网络引导
	domainXML.OS.Loader = &libvirtxml.DomainLoader{
		Type: "pflash",
		Path: "/usr/share/OVMF/OVMF_CODE.fd",
	}

	// 添加网络引导设备
	if len(spec.BootOrder) == 0 {
		spec.BootOrder = []string{"network", "hd"}
	}

	return s.createDomainFromXML(spec.Name, domainXML)
}

// createFromImportDisk 从磁盘映像导入创建虚拟机
func (s *Service) createFromImportDisk(spec *VMCreateWizardSpec) (*DomainInfo, error) {
	// 验证必需参数
	if spec.ImportDiskPath == "" {
		return nil, fmt.Errorf("import disk path is required for disk import")
	}

	// 如果需要复制磁盘，先进行复制操作
	finalDiskPath := spec.ImportDiskPath
	if spec.ImportCopy {
		// 这里需要实现磁盘复制逻辑
		// 暂时返回错误，表示该功能待实现
		return nil, fmt.Errorf("disk copy functionality not yet implemented")
	}

	// 使用导入的磁盘路径
	spec.DiskPath = finalDiskPath

	// 构建XML配置
	domainXML := s.buildWizardDomainXML(spec)

	return s.createDomainFromXML(spec.Name, domainXML)
}

// createManually 手动创建虚拟机
func (s *Service) createManually(spec *VMCreateWizardSpec) (*DomainInfo, error) {
	// 如果提供了自定义XML，直接使用
	if spec.CustomXML != "" {
		return s.CreateFromXML(spec.CustomXML)
	}

	// 否则使用向导配置构建XML
	domainXML := s.buildWizardDomainXML(spec)

	return s.createDomainFromXML(spec.Name, domainXML)
}

// buildWizardDomainXML 从向导规格构建libvirtxml.Domain
func (s *Service) buildWizardDomainXML(spec *VMCreateWizardSpec) *libvirtxml.Domain {
	// 转换内存单位为KiB
	memoryKiB := spec.Memory
	switch spec.MemoryUnit {
	case "GB":
		memoryKiB = spec.Memory * 1024 * 1024
	case "MB":
		memoryKiB = spec.Memory * 1024
	}

	// 构建基础域配置
	domain := &libvirtxml.Domain{
		Type: "kvm",
		Name: spec.Name,
		Memory: &libvirtxml.DomainMemory{
			Value: uint(memoryKiB),
			Unit:  "KiB",
		},
		VCPU: &libvirtxml.DomainVCPU{
			Value: uint(spec.VCPUs),
		},
		OS: &libvirtxml.DomainOS{
			Type: &libvirtxml.DomainOSType{
				Type: "hvm",
			},
		},
		Devices: &libvirtxml.DomainDeviceList{
			Disks:      []libvirtxml.DomainDisk{},
			Interfaces: []libvirtxml.DomainInterface{},
			Graphics:   []libvirtxml.DomainGraphic{},
		},
	}

	// 配置启动设备
	if len(spec.BootOrder) > 0 {
		var bootDevices []libvirtxml.DomainBootDevice
		for _, dev := range spec.BootOrder {
			bootDevices = append(bootDevices, libvirtxml.DomainBootDevice{Dev: dev})
		}
		domain.OS.BootDevices = bootDevices
	}

	// 配置引导加载器
	if spec.Loader != "" {
		domain.OS.Loader = &libvirtxml.DomainLoader{
			Type: "pflash",
			Path: "/usr/share/OVMF/OVMF_CODE.fd",
		}
		if spec.Loader == "bios" {
			domain.OS.Loader = nil
		}
	}

	// 添加磁盘设备
	if spec.DiskSize > 0 || spec.DiskPath != "" {
		disk := libvirtxml.DomainDisk{
			Device: "disk",
			Driver: &libvirtxml.DomainDiskDriver{
				Name:  "qemu",
				Type:  spec.DiskFormat,
				Cache: spec.CacheMode,
			},
			Target: &libvirtxml.DomainDiskTarget{
				Dev: "vda",
				Bus: spec.DiskBus,
			},
		}

		// 设置磁盘源
		if spec.DiskPath != "" {
			disk.Source = &libvirtxml.DomainDiskSource{
				File: &libvirtxml.DomainDiskSourceFile{
					File: spec.DiskPath,
				},
			}
		}

		domain.Devices.Disks = append(domain.Devices.Disks, disk)
	}

	// 添加网络接口
	if spec.NetworkType != "" && spec.NetworkName != "" {
		netInterface := libvirtxml.DomainInterface{
			Model: &libvirtxml.DomainInterfaceModel{
				Type: spec.NetworkModel,
			},
		}

		switch spec.NetworkType {
		case "bridge":
			netInterface.Source = &libvirtxml.DomainInterfaceSource{
				Bridge: &libvirtxml.DomainInterfaceSourceBridge{
					Bridge: spec.NetworkName,
				},
			}
		case "network":
			netInterface.Source = &libvirtxml.DomainInterfaceSource{
				Network: &libvirtxml.DomainInterfaceSourceNetwork{
					Network: spec.NetworkName,
				},
			}
		case "user":
			netInterface.Source = &libvirtxml.DomainInterfaceSource{
				User: &libvirtxml.DomainInterfaceSourceUser{},
			}
		}

		// 设置MAC地址
		if spec.MACAddress != "" {
			netInterface.MAC = &libvirtxml.DomainInterfaceMAC{
				Address: spec.MACAddress,
			}
		}

		domain.Devices.Interfaces = append(domain.Devices.Interfaces, netInterface)
	}

	// 添加图形设备
	if spec.Graphics != "" {
		var graphic libvirtxml.DomainGraphic
		switch spec.Graphics {
		case "vnc":
			graphic.VNC = &libvirtxml.DomainGraphicVNC{
				Port:     -1,
				AutoPort: "yes",
				Listen:   "127.0.0.1",
			}
		case "spice":
			graphic.Spice = &libvirtxml.DomainGraphicSpice{
				Port:     -1,
				AutoPort: "yes",
			}
		}
		domain.Devices.Graphics = append(domain.Devices.Graphics, graphic)
	}

	return domain
}

// createDomainFromXML 从libvirtxml.Domain创建虚拟机
func (s *Service) createDomainFromXML(_ string, domainXML *libvirtxml.Domain) (*DomainInfo, error) {
	xmlBytes, err := xml.MarshalIndent(domainXML, "", "  ")
	if err != nil {
		return nil, fmt.Errorf("failed to marshal domain XML: %w", err)
	}

	log.Debugf("Creating domain with XML:\n%s", string(xmlBytes))

	var info *DomainInfo
	err = s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.DomainDefineXML(string(xmlBytes))
		if err != nil {
			return fmt.Errorf("failed to define domain: %w", err)
		}
		defer dom.Free()

		info, err = s.getDomainInfo(dom, false)
		return err
	})

	return info, err
}

// UpdateByUUID 通过UUID更新虚拟机配置
func (s *Service) UpdateByUUID(uuid string, spec *UpdateSpec) (*DomainInfo, error) {
	var info *DomainInfo

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		// 查找虚拟机
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		// 获取当前XML配置
		xmlDesc, err := dom.GetXMLDesc(0)
		if err != nil {
			return fmt.Errorf("failed to get domain XML: %w", err)
		}

		// 解析XML
		var domainDef libvirtxml.Domain
		if err := xml.Unmarshal([]byte(xmlDesc), &domainDef); err != nil {
			return fmt.Errorf("failed to parse domain XML: %w", err)
		}

		// 检查虚拟机状态
		state, _, err := dom.GetState()
		if err != nil {
			return fmt.Errorf("failed to get domain state: %w", err)
		}

		// 根据状态决定是否可以进行热更新
		isRunning := state == libvirt.DOMAIN_RUNNING

		// 更新配置
		if spec.Name != "" && spec.Name != domainDef.Name {
			// 检查新名称是否已存在
			if exists, err := s.Exists(spec.Name); err == nil && exists {
				return fmt.Errorf("domain name '%s' already exists", spec.Name)
			}
			domainDef.Name = spec.Name
		}

		if spec.Memory > 0 {
			if isRunning {
				// 运行时内存调整（热插拔）
				if err := dom.SetMemory(uint64(spec.Memory * 1024)); err != nil {
					log.Warnf("Failed to hot-set memory for domain %s: %v", uuid, err)
					// 回退到配置更新
				}
			}
			// 更新XML配置中的内存
			domainDef.Memory = &libvirtxml.DomainMemory{
				Value: uint(spec.Memory * 1024), // 转换为KiB
				Unit:  "KiB",
			}
		}

		if spec.VCPUs > 0 {
			if isRunning {
				// 运行时CPU调整（热插拔）
				if err := dom.SetVcpus(spec.VCPUs); err != nil {
					log.Warnf("Failed to hot-set vCPUs for domain %s: %v", uuid, err)
					// 回退到配置更新
				}
			}
			// 更新XML配置中的CPU
			domainDef.VCPU = &libvirtxml.DomainVCPU{
				Value: uint(spec.VCPUs),
			}
		}

		if spec.Autostart != nil {
			if err := dom.SetAutostart(*spec.Autostart); err != nil {
				return fmt.Errorf("failed to set autostart: %w", err)
			}
		}

		// 重新定义虚拟机（更新XML配置）
		updatedXML, err := xml.MarshalIndent(domainDef, "", "  ")
		if err != nil {
			return fmt.Errorf("failed to marshal updated domain XML: %w", err)
		}

		log.Debugf("Updating domain %s with XML:\n%s", uuid, string(updatedXML))

		// 重新定义域
		newDom, err := conn.DomainDefineXML(string(updatedXML))
		if err != nil {
			return fmt.Errorf("failed to redefine domain: %w", err)
		}
		defer newDom.Free()

		// 获取更新后的信息
		info, err = s.getDomainInfo(newDom, false)
		return err
	})

	return info, err
}

// GetVNCInfo 获取域的VNC连接信息
func (s *Service) GetVNCInfo(uuid string) (*VNCInfo, error) {
	var vncInfo *VNCInfo

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByUUIDString(uuid)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		// 获取域的XML描述
		xmlDesc, err := dom.GetXMLDesc(0)
		if err != nil {
			return fmt.Errorf("failed to get domain XML: %w", err)
		}

		// 解析XML
		var domainDef libvirtxml.Domain
		if err := xml.Unmarshal([]byte(xmlDesc), &domainDef); err != nil {
			return fmt.Errorf("failed to parse domain XML: %w", err)
		}

		// 查找VNC图形设备
		if domainDef.Devices != nil && len(domainDef.Devices.Graphics) > 0 {
			for _, graphic := range domainDef.Devices.Graphics {
				if graphic.VNC != nil {
					vnc := graphic.VNC
					display := 0
					port := vnc.Port
					if port >= 5900 {
						display = port - 5900
					}

					info := &VNCInfo{
						Host:          "127.0.0.1",    // 默认本地主机
						Port:          port,           // VNC端口
						WebSocketPort: 6900 + display, // WebSocket端口通常为6900 + display
					}

					// 如果有密码则设置
					if vnc.Passwd != "" {
						info.Password = vnc.Passwd
					}

					// 设置控制台WebSocket URL
					info.ConsoleWebSocketURL = fmt.Sprintf("/api/v1/domains/%s/vnc/websocket", uuid)

					vncInfo = info
					break
				}
			}
		}

		if vncInfo == nil {
			return fmt.Errorf("no VNC graphics device found for domain")
		}

		return nil
	})

	return vncInfo, err
}

// getDomainUUIDByName 根据名称获取域的UUID
func (s *Service) getDomainUUIDByName(name string) (string, error) {
	var uuid string

	err := s.connManager.WithConn(func(conn *libvirt.Connect) error {
		dom, err := conn.LookupDomainByName(name)
		if err != nil {
			return fmt.Errorf("domain not found: %w", err)
		}
		defer dom.Free()

		domainUUID, err := dom.GetUUIDString()
		if err != nil {
			return fmt.Errorf("failed to get domain UUID: %w", err)
		}

		uuid = domainUUID
		return nil
	})

	return uuid, err
}
